package md.frolov.bible.initializers;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import md.frolov.bible.Activator;
import md.frolov.bible.Constants;
import md.frolov.bible.indexes.IX;
import md.frolov.bible.indexes.IXBible;
import md.frolov.bible.indexes.IndexManager;
import md.frolov.bible.model.Archive;
import md.frolov.bible.model.Book;
import md.frolov.bible.model.Chapter;
import md.frolov.bible.model.Module;
import md.frolov.bible.model.Verse;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;


public class BookInitializator implements IInitializator {
	private IPath workspace;
	private File workspaceFile;
	private IPath stateLocation;
	private File stateLocationFile;

	@Override
	public void initialize() throws InitializationException {
		workspace = Platform.getLocation();
		workspaceFile = workspace.toFile();
		stateLocation = Activator.getInstance().getStateLocation();
		stateLocationFile = stateLocation.toFile();
		
		try{
			rambleStructure(workspaceFile);
			IndexManager.getInstance().save();
		} catch (IOException e){
			System.out.println("IOException");
			throw new InitializationException();
		}
	}

	private void rambleStructure(File f) throws IOException{
		if(f==null) return;
		if(f.isFile()){
			if (!f.getName().endsWith(".book")) return;

			parseFile(f);
		}
		if(f.isDirectory()){
			File[] list = f.listFiles();
			if(list==null) return;
			for (int i = 0; i < list.length; i++) {
				rambleStructure(list[i]);
			}
		}
	}
	
	private void parseFile(File file) throws IOException{
		boolean needReindex = IndexManager.getInstance().getIndex(file) == null;
		if(needReindex)
			IndexManager.getInstance().createIndex(file, IXBible.class.getName());
		else
			if (IndexManager.getInstance().getIndex(file).lastModified()==file.lastModified()){
				needReindex = false;
			}
		
		System.out.println("parsing file");
		try{
			long time1 = System.currentTimeMillis();
			(new CustomXMLParser(file)).parse(new BibleParsingHandler(file));
			System.out.println("Parsed in "+(System.currentTimeMillis()-time1)/1000.0+"s");
			
//			if(file.getName().equals("kjv.book")){
//				System.out.println("wow");
//				long time2 = System.currentTimeMillis();
//				CustomXMLParser cp = new CustomXMLParser(file);
////				Verse[] v = cp.getVerses(new String[]{"bible.jhn.3.15","bible.isa.40.12-bible.isa.40.14","bible.gen.1.1","bible.1ti.3.16","bible.jhn.3.16"});
//				Verse[] v = cp.getChapter("bible.jhn.1");
//				System.out.println("Fetched in "+(System.currentTimeMillis()-time2)/1000.0);
//				for(int i=0;i<v.length;i++){
//					System.out.println("Verse "+v[i].getId()+": "+v[i].getContents());
//				}
//			}
		} catch (Exception e){
			e.printStackTrace();
		}
//		try{
//			SAXParserFactory spf = SAXParserFactory.newInstance();
//			SAXParser sp = spf.newSAXParser();
//			long time1 = System.currentTimeMillis();
//			sp.parse(new InputSource(new InputStreamReader(new FileInputStream(file),"UTF-8")), new ThisHandler2(file));
//			
//			System.out.println("Parsing time: "+(System.currentTimeMillis()-time1)/1000.+"s");
//		} catch (Exception e){
//			e.printStackTrace();
//		}
	}
	
	private class ThisHandler2 extends DefaultHandler{
		Module lastModule;
		Book lastBook;
		File file;
		
		public ThisHandler2(File f){
			file = f;
		}

		
		@Override
		public void error(SAXParseException e) throws SAXException {
			System.out.println("something went wrong");
		}

		
		@Override
		public void startElement(String uri, String localName, String tag,	org.xml.sax.Attributes attributes) throws SAXException {
			if (tag.equals(Constants.XML_TAG_MODULE)){
				String id = attributes.getValue(Constants.XML_ATTRIBUTE_ID);
				lastModule = Archive.getInstance().getModuleByID(id);
				lastModule.setName(attributes.getValue(Constants.XML_ATTRIBUTE_NAME));
				lastModule.setShortName(attributes.getValue(Constants.XML_ATTRIBUTE_SHORT_NAME));
				lastModule.setCategory(attributes.getValue(Constants.XML_ATTRIBUTE_CATEGORY));
				lastModule.setLanguage(attributes.getValue(Constants.XML_ATTRIBUTE_LANGUAGE));
				lastModule.setFile(file);
				Archive.getInstance().addModuleStructure(lastModule);
			}
			
			if (tag.equals(Constants.XML_TAG_BOOK)){
				String id = attributes.getValue(Constants.XML_ATTRIBUTE_ID);
				lastBook = new Book(id);
				lastModule.addBook(lastBook);
				lastBook.setName(attributes.getValue(Constants.XML_ATTRIBUTE_NAME));
			}
			
			if(tag.equals(Constants.XML_CHAPTER_TAG)){
				String id = attributes.getValue(Constants.XML_ATTRIBUTE_ID);
				Chapter c = new Chapter(id);
				lastBook.addChapter(c);
				c.setName(attributes.getValue(Constants.XML_ATTRIBUTE_NAME));
			}
		}

		
		@Override
		public void endElement(String uri, String localName, String tag)throws SAXException {
			if(tag.equals(Constants.XML_TAG_MODULE)) lastModule = null;
			if(tag.equals(Constants.XML_TAG_BOOK)) lastBook = null;
			
		}
		
	}
	
}
